package cm.example.shoppingplatformspringboot.mapper;


import cm.example.shoppingplatformspringboot.entity.Category;
import cm.example.shoppingplatformspringboot.entity.Goods;
import cm.example.shoppingplatformspringboot.entity.Manager;
import cm.example.shoppingplatformspringboot.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

@Mapper
public interface AdminMapper {
    /**
     * 将管理员信息插入数据库。
     *
     * @param manager 管理员实体对象，需包含以下有效信息：
     *                - account   : 管理员账号
     *                - password  : 管理员密码
     * @return {@code int} 插入操作影响的行数（1-成功，0-失败）
     * @implNote 管理员默认状态：{@code status = 1}（正常）
     */
    @Insert("INSERT INTO wn_manager(account, password, status) " +
            "values(#{account}, #{password}, '1')")
    int addAdmin(Manager manager);

    /**
     * 逻辑删除管理员（标记删除状态）
     *
     * @param id 管理员ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status = 2}（已删除状态）
     */
    @Update("UPDATE wn_manager SET status = '2' WHERE id = #{id}")
    int deleteAdmin(int id);

    /**
     * 更新管理员账户信息
     *
     * @param manager 必须包含：
     *                - id        : 有效管理员ID
     *                - account   : 新账号
     *                - password  : 新密码
     * @return {@code int} 受影响行数（1-成功，0-失败）
     */
    @Update("UPDATE wn_manager SET account = #{account}, password = #{password} " +
            "WHERE id = #{id}")
    int editAdmin(Manager manager);

    /**
     * 获取全部管理员列表
     *
     * @return {@code List} 管理员实体列表（包含所有状态记录）
     * @implNote 状态说明：
     * - 0: 禁用
     * - 1: 正常
     * - 2: 已删除
     */
    @Select("SELECT * FROM wn_manager")
    List<Manager> getAdminList();

    /**
     * 禁用管理员账户
     *
     * @param id 管理员ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status=0}（禁用）
     */
    @Update("UPDATE wn_manager SET status = '0' WHERE id = #{id}")
    int disableAdmin(int id);

    /**
     * 解禁管理员账户
     *
     * @param id 管理员ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status=1}（正常）
     */
    @Update("UPDATE wn_manager SET status = '1' WHERE id = #{id}")
    int unDisableAdmin(int id);

    /**
     * 获取全部用户列表
     *
     * @return {@code List} 用户实体列表（包含所有信息）
     * @implNote 用户状态说明：
     * - 0: 冻结
     * - 1: 正常
     * - 2: 拉黑
     */
    @Select("SELECT * FROM wn_user WHERE status != '3'")
    List<User> getUserList();

    /**
     * 逻辑删除用户记录
     *
     * @param id 用户ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     */
    @Delete("UPDATE wn_user SET status = '3' WHERE id = #{id}")
    int deleteUser(int id);

    /**
     * 拉黑用户
     *
     * @param id 用户ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status=2}（拉黑）
     */
    @Update("UPDATE wn_user SET status = '2' WHERE id = #{id}")
    int blockUser(int id);

    /**
     * 解除用户黑名单
     *
     * @param id 用户ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 恢复 {@code status=1}（正常）
     */
    @Update("UPDATE wn_user SET status = '1' WHERE id = #{id}")
    int unblockUser(int id);

    /**
     * 冻结用户账户
     *
     * @param id 用户ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status=0}（冻结）
     */
    @Update("UPDATE wn_user SET status = '0' WHERE id = #{id}")
    int freezeUser(int id);

    /**
     * 解冻用户账户
     *
     * @param id 用户ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 恢复 {@code status=1}（正常）
     */
    @Update("UPDATE wn_user SET status = '1' WHERE id = #{id}")
    int unfreezeUser(int id);

    /**
     * 新增商品分类
     *
     * @param name 分类名称
     * @return {@code int} 受影响行数（1-成功，0-失败）
     */
    @Insert("INSERT INTO wn_category(name) VALUES(#{name})")
    int addProductType(String name);

    /**
     * 获取带商品统计的分类列表
     *
     * @return {@code List} 分类实体列表，包含：
     * - id     : 分类ID
     * - name   : 分类名称
     * - number : 关联商品数量
     * - pid    : 父级分类ID
     */
    @Select("SELECT c.*, COUNT(g.id) AS number FROM wn_category c " +
            "LEFT JOIN wn_goods g ON c.id = g.category_id " +
            "GROUP BY c.id")
    List<Category> getProductTypeList();

    /**
     * 物理删除商品分类
     *
     * @param id 分类ID（必须存在）
     */
    @Delete("DELETE FROM wn_category WHERE id = #{id}")
    void deleteProductType(int id);

    /**
     * 获取某个商品数量
     *
     * @param id 分类ID
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 统计某个商品数量
     */
    @Select("SELECT COUNT(*) FROM wn_goods g " +
            "LEFT JOIN wn_category c ON c.id = g.category_id " +
            "WHERE c.id = #{id} ")
    int getProductNumber(int id);

    /**
     * 获取全量商品列表（倒序排列）
     *
     * @return {@code List} 商品实体列表，包含：
     * - category_name : 关联分类名称
     * @implNote 商品状态说明：
     * - Y: 销售中
     * - A: 已上架
     * - D: 已删除
     */
    @Select("SELECT g.*, c.name AS category_name FROM wn_goods g " +
            "LEFT JOIN wn_category c ON c.id = g.category_id " +
            "ORDER BY g.id DESC")
    List<Goods> selectAll();

    /**
     * 获取分类ID-名称映射表
     *
     * @return {@code List<Map<String, Object>} Map列表，结构：
     * - id   : 分类ID（Integer）
     * - name : 分类名称（String）
     * @implNote 用于前端下拉框选项
     */
    @Select("SELECT id, name FROM wn_category")
    List<Map<String, Object>> getAllShopGenres();

    /**
     * 按分类名称获取商品列表
     *
     * @param value 分类名称（精确匹配）
     * @return {@code List} 商品实体列表（倒序排列）
     * @implNote 返回结果包含分类名称字段
     */
    @Select("select g.*, c.name AS category_name from wn_category c " +
            "LEFT JOIN wn_goods g ON c.id = g.category_id " +
            "where c.name = #{value} " +
            "ORDER BY g.id DESC")
    List<Goods> getGoodsListByGenre(String value);

    /**
     * 商品名称模糊搜索
     *
     * @param input 搜索关键词
     * @return {@code List} 匹配商品列表
     */
    @Select("select * from wn_goods where name LIKE CONCAT('%', #{input}, '%') ")
    List<Goods> searchGoods(String input);

    /**
     * 商品名称自动补全搜索
     *
     * @param name 名称片段
     * @return {@code List} 匹配的商品名称列表
     */
    @Select("select name from wn_goods where name LIKE CONCAT('%', #{name}, '%') ")
    List<String> searchGoodsByName(String name);

    /**
     * 逻辑删除商品
     *
     * @param id 商品ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status='D'}（删除状态）
     */
    @Update("update wn_goods set status = 'D' where id = #{id}")
    int deleteGoods(int id);

    /**
     * 商品上架操作
     *
     * @param id 商品ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status='A'}（上架）
     */
    @Update("update wn_goods set status = 'A' where id = #{id}")
    int soldOutGoods(int id);

    /**
     * 商品下架操作
     *
     * @param id 商品ID（必须存在）
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 设置 {@code status='Y'}（下架）
     */
    @Update("update wn_goods set status = 'Y' where id = #{id}")
    int putOnShelfGoods(int id);

    /**
     * 新增商品
     *
     * @param goods 商品实体，必须包含：
     *              - name          : 商品名称
     *              - category_id   : 有效分类ID
     *              - no            : 商品编号
     *              - market_price  : 市场价（≥0）
     *              - sale_price    : 售价（≥0）
     *              - stock         : 库存（≥0）
     *              - description   : 商品描述
     * @return {@code int} 受影响行数（1-成功，0-失败）
     * @implNote 自动设置：
     * - hottest='N'（非热销）
     * - newest='Y'（新品标记）
     * - sale_time=NOW()
     * - 初始状态为'Y'（待售）
     */
    @Insert("insert into wn_goods(name,category_id,no,market_price,sale_price,stock,image,hottest,newest,description,sale_time,status) " +
            "values(#{name},#{category_id},#{no},#{market_price},#{sale_price},#{stock},#{image},'N','Y',#{description},NOW(),'Y')")
    int addGoods(Goods goods);

    /**
     * 更新商品信息
     *
     * @param goods 必须包含：
     *              - id            : 有效商品ID
     *              - name          : 新名称
     *              - category_id   : 新分类ID
     *              - no            : 新编号
     *              - market_price  : 新市场价
     *              - sale_price    : 新售价
     *              - stock         : 新库存
     *              - description   : 新描述
     * @return {@code int} 受影响行数（1-成功，0-失败）
     */
    @Update("update wn_goods set name = #{name},category_id = #{category_id},no = #{no}," +
            "market_price = #{market_price},sale_price = #{sale_price},stock = #{stock}," +
            "image = #{image},description = #{description} where id = #{id}")
    int editGoods(Goods goods);

    /**
     * 根据账号查询管理员
     *
     * @param account 管理员账号（精确匹配）
     * @return 管理员实体（未找到返回null）
     */
    @Select("select * from wn_manager where account = #{account}")
    Manager getAdminByAccount(String account);

    /**
     * 更新管理员登录信息
     *
     * @param account 管理员账号（精确匹配）
     * @param ip      登录IP
     * @implNote 同时更新last_login_time为当前时间
     */
    @Update("update wn_manager set last_login_time = NOW(), last_login_ip = #{ip} where account = #{account}")
    void updateAdminLoginInfo(@Param("account") String account, @Param("ip") String ip);
}
